<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="AsciiDoc 8.6.8">
<title>Facebook的工具</title>
<link rel="stylesheet" href="../../../asciidoc/css/flask.css" type="text/css">

<link rel="stylesheet" href="../../../asciidoc/css/pygments.css" type="text/css">

<link rel="stylesheet" href="../../../asciidoc/css/toc2.css" type="text/css" />
<script type="text/javascript" src="../../../asciidoc/js/asciidoc.js"></script>
<script type="text/javascript" src="../../../asciidoc/js/flask.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install(2);
/*]]>*/
</script>
</head>
<body class="article" style="max-width:900">
<div id="header">
<h1>Facebook的工具</h1>
<span id="author">李飞</span><br>
<span id="email" class="monospaced">&lt;<a href="mailto:lifei@7v1.net">lifei@7v1.net</a>&gt;</span><br>
<span id="revnumber">version 1.0.0</span>
<div id="toc">
  <div id="toctitle">目录</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_背景">1. 背景</h2>
<div class="sectionbody">
<div class="paragraph"><p>今天将facebook的rocksdb拉下来研究了一下。
早就听说facebook把最聪明的人都安排在工具组，
刚好rocksdb目录下有个build_tools的目录，
里面有一些工具的脚本，不确定这些脚本是不是网上所传的new
bee工具，但是这应该是facebook工程师日常开发生活所用的动动。</p></div>
<div class="listingblock">
<div class="title">build_tools目录文件</div>
<div class="content monospaced">
<pre>ThinkPad-X201:~/Workspaces/c++/rocksdb
lifei$ ls build_tools/
build_detect_platform  fbcode.clang31.sh  format-diff.sh         regression_build_test.sh
build_detect_version   fbcode.gcc471.sh   mac-install-gflags.sh  valgrind_test.sh
clang-format-diff.py   fbcode.gcc481.sh   make_new_version.sh</pre>
</div></div>
</div>
</div>
<div class="sect1">
<h2 id="_format_diff_sh">2. format-diff.sh</h2>
<div class="sectionbody">
<div class="paragraph"><p>先研究了一下 <span class="monospaced">format-diff.sh</span> 脚本，这个文件下有一段注释，是一个TODO，
facebook中有个叫刘凯的工程师（音译）需要做一些事情完善这个脚本。</p></div>
<div class="listingblock">
<div class="title">TOOD注释</div>
<div class="content"><div class="highlight"><pre><span class="c"># TODO(kailiu) following work is not complete since we still need to figure</span>
<span class="c"># out how to add the modified files done pre-commit hook to git&#39;s commit index.</span>
<span class="c">#</span>
<span class="c"># Check if this script has already been added to pre-commit hook.</span>
<span class="c"># Will suggest user to add this script to pre-commit hook if their pre-commit</span>
<span class="c"># is empty.</span>
<span class="c"># PRE_COMMIT_SCRIPT_PATH=&quot;`git rev-parse --show-toplevel`/.git/hooks/pre-commit&quot;</span>
<span class="c"># if ! ls $PRE_COMMIT_SCRIPT_PATH &amp;&gt; /dev/null</span>
<span class="c"># then</span>
<span class="c">#   echo &quot;Would you like to add this script to pre-commit hook, which will do &quot;</span>
<span class="c">#   echo -n &quot;the format check for all the affected lines before you check in (y/n):&quot;</span>
<span class="c">#   read add_to_hook</span>
<span class="c">#   if [ &quot;$add_to_hook&quot; == &quot;y&quot; ]</span>
<span class="c">#   then</span>
<span class="c">#     ln -s `git rev-parse --show-toplevel`/build_tools/format-diff.sh $PRE_COMMIT_SCRIPT_PATH</span>
<span class="c">#   fi</span>
<span class="c"># fi</span>
</pre></div></div></div>
<div class="paragraph"><p>大体意思就是每次commit代码之前要让程序将提交的代码格式化一下，new bee啊。</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_coverage">3. coverage</h2>
<div class="sectionbody">
<div class="paragraph"><p>coverage目录下的文件</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>ThinkPad-X201:~/Workspaces/c++/rocksdb/coverage
lifei$ ls
COVERAGE_REPORT  coverage_test.sh  parse_gcov_output.py</pre>
</div></div>
<div class="paragraph"><p>使用 <span class="monospaced">gcov</span> 进行覆盖度检测。</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_附录">4. 附录</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="title">format-diff.sh</div>
<div class="content"><div class="highlight"><pre><span class="c">#!/bin/bash</span>
<span class="c"># If clang_format_diff.py command is not specfied, we assume we are able to</span>
<span class="c"># access directly without any path.</span>
<span class="k">if</span> <span class="o">[</span> -z <span class="nv">$CLANG_FORMAT_DIFF</span> <span class="o">]</span>
<span class="k">then</span>
<span class="nv">CLANG_FORMAT_DIFF</span><span class="o">=</span><span class="s2">&quot;clang-format-diff.py&quot;</span>
<span class="k">fi</span>

<span class="c"># Check clang-format-diff.py</span>
<span class="k">if</span> ! which <span class="nv">$CLANG_FORMAT_DIFF</span> &amp;&gt; /dev/null
<span class="k">then</span>
<span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;You didn&#39;t have clang-format-diff.py available in your computer!&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;You can download it by running: &quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;    curl http://goo.gl/iUW1u2&quot;</span>
  <span class="nb">exit </span>128
<span class="k">fi</span>

<span class="c"># Check argparse, a library that clang-format-diff.py requires.</span>
python 2&gt;/dev/null <span class="s">&lt;&lt; EOF</span>
<span class="s">import argparse</span>
<span class="s">EOF</span>

<span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$?&quot;</span> !<span class="o">=</span> 0 <span class="o">]</span>
<span class="k">then</span>
<span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;To run clang-format-diff.py, we&#39;ll need the library &quot;</span>argparse<span class="s2">&quot; to be&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;installed. You can try either of the follow ways to install it:&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;  1. Manually download argparse: https://pypi.python.org/pypi/argparse&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;  2. easy_install argparse (if you have easy_install)&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;  3. pip install argparse (if you have pip)&quot;</span>
  <span class="nb">exit </span>129
<span class="k">fi</span>

<span class="c"># TODO(kailiu) following work is not complete since we still need to figure</span>
<span class="c"># out how to add the modified files done pre-commit hook to git&#39;s commit index.</span>
<span class="c">#</span>
<span class="c"># Check if this script has already been added to pre-commit hook.</span>
<span class="c"># Will suggest user to add this script to pre-commit hook if their pre-commit</span>
<span class="c"># is empty.</span>
<span class="c"># PRE_COMMIT_SCRIPT_PATH=&quot;`git rev-parse --show-toplevel`/.git/hooks/pre-commit&quot;</span>
<span class="c"># if ! ls $PRE_COMMIT_SCRIPT_PATH &amp;&gt; /dev/null</span>
<span class="c"># then</span>
<span class="c">#   echo &quot;Would you like to add this script to pre-commit hook, which will do &quot;</span>
<span class="c">#   echo -n &quot;the format check for all the affected lines before you check in (y/n):&quot;</span>
<span class="c">#   read add_to_hook</span>
<span class="c">#   if [ &quot;$add_to_hook&quot; == &quot;y&quot; ]</span>
<span class="c">#   then</span>
<span class="c">#     ln -s `git rev-parse --show-toplevel`/build_tools/format-diff.sh $PRE_COMMIT_SCRIPT_PATH</span>
<span class="c">#   fi</span>
<span class="c"># fi</span>

<span class="nb">set</span> -e

<span class="nv">uncommitted_code</span><span class="o">=</span><span class="sb">`</span>git diff HEAD<span class="sb">`</span>

<span class="c"># If there&#39;s no uncommitted changes, we assume user are doing post-commit</span>
<span class="c"># format check, in which case we&#39;ll check the modified lines from latest commit.</span>
<span class="c"># Otherwise, we&#39;ll check format of the uncommitted code only.</span>
<span class="nv">format_last_commit</span><span class="o">=</span>0
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;$uncommitted_code&quot;</span> <span class="o">]</span>
<span class="k">then</span>
  <span class="c"># Check the format of last commit</span>
  <span class="nv">diffs</span><span class="o">=</span><span class="k">$(</span>git diff -U0 HEAD^ | <span class="nv">$CLANG_FORMAT_DIFF</span> -p 1<span class="k">)</span>
  <span class="nb">echo</span> <span class="nv">$uncommitted_code</span>
  <span class="nb">echo</span> <span class="nv">$diffs</span>
<span class="k">else</span>
  <span class="c"># Check the format of uncommitted lines,</span>
  <span class="nv">diffs</span><span class="o">=</span><span class="k">$(</span>git diff -U0 HEAD | <span class="nv">$CLANG_FORMAT_DIFF</span> -p 1<span class="k">)</span>
  <span class="nb">echo</span> <span class="nv">$uncommitted_code</span>
  <span class="nb">echo</span> <span class="nv">$diffs</span>
<span class="k">fi</span>

<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;$diffs&quot;</span> <span class="o">]</span>
<span class="k">then</span>
<span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;Nothing needs to be reformatted!&quot;</span>
  <span class="c"># exit 0</span>
<span class="k">fi</span>

<span class="c"># Highlight the insertion/deletion from the clang-format-diff.py&#39;s output</span>
<span class="nv">COLOR_END</span><span class="o">=</span><span class="s2">&quot;\033[0m&quot;</span>
<span class="nv">COLOR_RED</span><span class="o">=</span><span class="s2">&quot;\033[0;31m&quot;</span>
<span class="nv">COLOR_GREEN</span><span class="o">=</span><span class="s2">&quot;\033[0;32m&quot;</span>

<span class="nb">echo</span> -e <span class="s2">&quot;Detect lines that doesn&#39;t follow the format rules:\r&quot;</span>
<span class="c"># Add the color to the diff. lines added will be green; lines removed will be red.</span>
<span class="nb">echo</span> <span class="s2">&quot;$diffs&quot;</span> |
  sed -e <span class="s2">&quot;s/\(^-.*$\)/`echo -e \&quot;$COLOR_RED\1$COLOR_END\&quot;`/&quot;</span> |
  sed -e <span class="s2">&quot;s/\(^+.*$\)/`echo -e \&quot;$COLOR_GREEN\1$COLOR_END\&quot;`/&quot;</span>
<span class="nb">echo</span> -e <span class="s2">&quot;Would you like to fix the format automatically (y/n): \c&quot;</span>

<span class="c"># Make sure under any mode, we can read user input.</span>
<span class="nb">exec</span> &lt; /dev/tty
<span class="nb">read </span>to_fix

<span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$to_fix&quot;</span> !<span class="o">=</span> <span class="s2">&quot;y&quot;</span> <span class="o">]</span>
<span class="k">then</span>
<span class="k">  </span><span class="nb">exit </span>1
<span class="k">fi</span>

<span class="c"># Do in-place format adjustment.</span>
git diff -U0 HEAD^ | <span class="nv">$CLANG_FORMAT_DIFF</span> -i -p 1
<span class="nb">echo</span> <span class="s2">&quot;Files reformatted!&quot;</span>

<span class="c"># Amend to last commit if user do the post-commit format check</span>
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;$uncommitted_code&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">  </span><span class="nb">echo</span> -e <span class="s2">&quot;Would you like to amend the changes to last commit (`git log HEAD --oneline | head -1`)? (y/n): \c&quot;</span>
  <span class="nb">read </span>to_amend

  <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$to_amend&quot;</span> <span class="o">==</span> <span class="s2">&quot;y&quot;</span> <span class="o">]</span>
  <span class="k">then</span>
<span class="k">    </span>git commit -a --amend --reuse-message HEAD
    <span class="nb">echo</span> <span class="s2">&quot;Amended to last commit&quot;</span>
  <span class="k">fi</span>
<span class="k">fi</span>
</pre></div></div></div>
<div class="paragraph"><p><a href="../../index.html">返回首页</a></p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
Version 1.0.0<br>
Last updated 2014-01-20 02:06:31 CST
</div>
</div>
</body>
</html>
